/**
 * java语言必须以 分号  结尾
 * 计算机二进制语言的特点
 *  1. 二进制语言是计算机唯一能够理解的语言；
 *  2. 二进制语言是由0和1组成的；
 *  3. 二进制语言的最高位是符号位，0表示正数，1表示负数；
 *  4. 二进制语言的运算符只有加减乘除和取模；
 *  5. 二进制语言的变量只有0和1；
 * 算法:
 *  1. 整数: 计算机中的整数是以二进制补码的形式存储的，整数的运算包括加减乘除和取模；
 *      byte是1字节，short是2字节，int是4字节，long是8字节；分别是8位、16位、32位、64位二进制形式存在的；
 *      例如int类型是4字节，范围是-2147483648~2147483647，如果超出这个范围就会产生溢出；这个范围计算公式是：-2^31~2^31-1；是以32位二进制表示的，最高位是符号位，0表示正数，1表示负数；
 *    1.1 整数由于存在范围限制，如果计算结果超出了范围就会产生溢出，溢出不会报错会出现一个特别奇怪的结果
 *    1.2 位运算：左移、右移、无符号右移、按位与、按位或、按位异或、取反；
 *          以下涉及的高位和低位都是指二进制数的高位和低位；
 *        << 有符号左移：将二进制数向左移动指定位数，低位补0；
 *        >> 有符号右移：将二进制数向右移动指定位数，高位丢弃；
 *        >>> 无符号右移：将二进制数向右移动指定位数，高位补0；
 *        & 按位与：两个二进制数对应位相与，结果为1则为1，否则为0；
 *        | 按位或：两个二进制数对应位相或，结果为1则为1，否则为0；
 *        ^ 按位异或：两个二进制数对应位相异或，结果为1则为1，否则为0；
 *        ~ 取反：对二进制数按位取反，即0变1，1变0；
 *        位运算的优先级是：括号>按位与>按位异或>按位或>左移>右移>无符号右移；
 *   1.3 优先级
 *      括号>一元运算符>乘除法>加减法>左移、右移、无符号右移>按位与、按位或、按位异或>逻辑运算符>赋值运算符；
 *   1.4 强制类型转换
 *      通过括号的方式进行强制类型转换，例如：int n = (int)3.14；
 * 
 * 浮点数运算：
 *  1. 和整数运算不同，浮点数运算只能进行加减乘除，不能进行位运算；
 *  2. 浮点数运算存在舍入误差，例如：0.1+0.2的结果不是0.3；
 * 
 * 类型提升：
 *  1. 当两个不同类型的数据进行运算时，会自动将其中一个数据类型提升为另一个数据类型，然后再进行运算；
 *  注意： 复杂的四则运算中，两个整数的运算不会出现自动提升的情况
 */

public class Algorithm {
    public Algorithm() {
        System.out.println("Algorithm constructor called.");
    }
    public static void main(String[] args) {
        int x = 2147483640;
        int y = 15;
        int sum = x + y;
        long sum2 = (long)x + y;
        System.out.println(sum); // -2147483641
        System.out.println(sum2); // 2147483655
        int n = 7;
        /**
         * 7的二进制表示是：0000 0000 0000 0000 0000 0000 0000 0111
         * 左移29位后会变为 1110 0000 0000 0000 0000 0000 0000 0000
         * 二进制转换为十进制是：-536870912
         * 左移30位后会变为 1100 0000 0000 0000 0000 0000 0000 0000
         * 二进制转换为十进制是：-1073741824
         */
        int d = n << 29;
        int d2 = n << 30;
        System.out.println(d); // -536870912
        System.out.println(d2);

        int m = -536870912;
        int m1 = m >> 1;
        int m2 = m >> 2;
        System.out.println(m1); // -268435456
        System.out.println(m2); // -134217728
        int m3 = m >> 28;
        int m4 = m >> 29;
        System.out.println(m3); // -2
        System.out.println(m4); // -1
        int m5 = m >> 30;
        int m6 = m >> 31;
        System.out.println(m5); // -1

        int e = -55;
        int n1 = e >> 1;
        int n2 = e >> 2;
        System.out.println(n1); // -28
        System.out.println(n2);  // -14

        /**
         * j的值不存在类型提升，因为j的值是一个复杂的四则运算，所以两个整数的运算不会出现自动提升的情况；
         * j2的值存在类型提升；
         */
        double j = 1.2 + 24 / 5;
        double j2 = 1.2 + 24.0 / 5;
        System.out.println(j); // 5.2
        System.out.println(j2); // 6.8

        /**
         * 整数运算在除数为0时会报错，浮点数运算在除数为0时会返回Infinity， -Infinity，NaN这几个特殊值；
         */
        // int a = 5 /0;
        // System.out.println(a); // Exception in thread "main" java.lang.ArithmeticException: / by zero
        double b = 5.0 / 0;
        System.out.println(b); // Infinity
        double c = -5.0 / 0;
        System.out.println(c); // -Infinity
        double d3 = 0.0 / 0;
        System.out.println(d3); // NaN
    }
}
